﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Telerik.Windows.Documents.Fixed.FormatProviders.Pdf;
using Telerik.Windows.Documents.Fixed.Model;
using Telerik.Windows.Documents.Fixed.Model.ColorSpaces;
using Telerik.Windows.Documents.Fixed.Model.Editing;
using Telerik.Windows.Documents.Fixed.Model.Editing.Tables;
using Telerik.Windows.Documents.Flow.FormatProviders.Html;
using Telerik.Windows.Documents.Flow.Model;

namespace Console_4._7._2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            RadFlowDocument htmlDocument;
            HtmlFormatProvider htmlFormatProvider = new HtmlFormatProvider();

            using (Stream input = File.OpenRead("..\\..\\..\\input.html"))
            {
                htmlDocument = htmlFormatProvider.Import(input, null);
            }

            Telerik.Windows.Documents.Flow.Model.Table htmlTable = htmlDocument.EnumerateChildrenOfType<Telerik.Windows.Documents.Flow.Model.Table>().FirstOrDefault();

            if (htmlTable == null)
            {
                System.Console.WriteLine("No table found in the HTML document.");
                return;
            }

            RadFixedDocument pdfDocument = new RadFixedDocument();
            
            // Convert HTML table to PDF tables across multiple pages
            ConvertHtmlTableToPdf(htmlTable, pdfDocument);

            // Save the PDF document
            PdfFormatProvider pdfProvider = new PdfFormatProvider();
            using (Stream output = File.Create("output.pdf"))
            {
                pdfProvider.Export(pdfDocument, output);
            }

            var psi = new ProcessStartInfo()
            {
                FileName = "output.pdf",
                UseShellExecute = true
            };
            Process.Start(psi);



        }

        static void ConvertHtmlTableToPdf(Telerik.Windows.Documents.Flow.Model.Table htmlTable, RadFixedDocument pdfDocument)
        {
            const double pageMargin = 72; // 1 inch margin
            const double maxTableWidth = 595.2 - (2 * pageMargin); // A4 width minus margins
            const double maxTableHeight = 841.8 - (2 * pageMargin); // A4 height minus margins

            RadFixedPage currentPage = pdfDocument.Pages.AddPage();
            FixedContentEditor currentEditor = new FixedContentEditor(currentPage);
            
            Telerik.Windows.Documents.Fixed.Model.Editing.Tables.Table currentPdfTable = new Telerik.Windows.Documents.Fixed.Model.Editing.Tables.Table();
            double currentTableHeight = 0;

            // Get all rows from the HTML table
            var htmlRows = htmlTable.Rows.ToList();
            int columnCount = htmlRows.Count > 0 ? htmlRows[0].Cells.Count : 0;
            
            for (int rowIndex = 0; rowIndex < htmlRows.Count; rowIndex++)
            {
                var htmlRow = htmlRows[rowIndex];
                
                // Calculate estimated row height BEFORE adding it to the table
                double estimatedRowHeight = CalculateEstimatedRowHeightFromHtmlRow(htmlRow);
                double projectedTableHeight = currentTableHeight + estimatedRowHeight;
                
                // Check if adding this row would exceed page height
                if (projectedTableHeight > maxTableHeight && currentPdfTable.Rows.Count > 0)
                {
                    // Draw the current table on the page (without the current row)
                    DrawTableOnPage(currentEditor, currentPdfTable, pageMargin);
                    
                    // Create a new page and table
                    currentPage = pdfDocument.Pages.AddPage();
                    currentEditor = new FixedContentEditor(currentPage);
                    currentPdfTable = new Telerik.Windows.Documents.Fixed.Model.Editing.Tables.Table();
                    currentTableHeight = 0;
                }
                
                // Now add the current row to the table (either current or new)
                var pdfRow = currentPdfTable.Rows.AddTableRow();
                
                // Copy cells from HTML row to PDF row
                for (int cellIndex = 0; cellIndex < htmlRow.Cells.Count; cellIndex++)
                {
                    var htmlCell = htmlRow.Cells[cellIndex];
                    var pdfCell = pdfRow.Cells.AddTableCell();
                    
                    // Copy cell content
                    foreach (var block in htmlCell.Blocks)
                    {
                        if (block is Paragraph paragraph)
                        {
                            Block newParagraph = new Block();
                            foreach (var inline in paragraph.Inlines)
                            {
                                if (inline is Run run)
                                {
                                    newParagraph.InsertText(run.Text);
                                }
                            }
                            pdfCell.Blocks.Add(newParagraph);
                        }
                    }
                    
                    // Set cell properties with basic padding
                    var cellBorder = new Border(1, new RgbColor(0, 0, 0));
                    pdfCell.Borders = new TableCellBorders(cellBorder, cellBorder, cellBorder, cellBorder);
                    pdfCell.PreferredWidth = maxTableWidth / columnCount;
                }
                
                // Update the current table height
                currentTableHeight += estimatedRowHeight;
            }
            
            // Draw the final table if it has rows
            if (currentPdfTable.Rows.Count > 0)
            {
                DrawTableOnPage(currentEditor, currentPdfTable, pageMargin);
            }
        }

        static double CalculateEstimatedRowHeightFromHtmlRow(Telerik.Windows.Documents.Flow.Model.TableRow htmlRow)
        {
            // Calculate estimated row height from HTML row before converting to PDF
            double baseRowHeight = 25; // Base height for a row
            double maxCellHeight = baseRowHeight;
            
            foreach (var htmlCell in htmlRow.Cells)
            {
                double cellHeight = baseRowHeight;
                
                // Add height for each block of content
                foreach (var block in htmlCell.Blocks)
                {
                    if (block is Paragraph paragraph)
                    {
                        // Count lines of text (approximate)
                        int textLength = 0;
                        foreach (var inline in paragraph.Inlines)
                        {
                            if (inline is Run run)
                            {
                                textLength += run.Text.Length;
                            }
                        }
                        
                        // Estimate lines based on character count (assuming ~50 chars per line)
                        int estimatedLines = Math.Max(1, textLength / 50);
                        cellHeight += (estimatedLines - 1) * 15; // Additional height for extra lines
                    }
                    else
                    {
                        cellHeight += 15; // Approximate height per non-paragraph block
                    }
                }
                
                if (cellHeight > maxCellHeight)
                {
                    maxCellHeight = cellHeight;
                }
            }
            
            return maxCellHeight;
        }

        static void DrawTableOnPage(FixedContentEditor editor, Telerik.Windows.Documents.Fixed.Model.Editing.Tables.Table table, double margin)
        {
            // Set table position
            editor.Position.Translate(margin, margin);
            
            // Draw the table
            editor.DrawTable(table);
        }
    }
}
